/*
 * *******************************************************************
 *   @项目名称: BHex Android
 *   @文件名称: KlineFragmentPresenter.java
 *   @Date: 18-11-29 下午4:05
 *   @Author: ppzhao
 *   @Description:
 *   @Copyright（C）: 2018 BlueHelix Inc.   All rights reserved.
 *   注意：本内容仅限于内部传阅，禁止外泄以及用于其他的商业目的.
 *  *******************************************************************
 */

package io.bhex.app.kline.presenter;

import android.annotation.SuppressLint;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;

import com.bhex.kline.KLineEntity;
import com.bhex.kline.KlineKind;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import io.bhex.app.base.AppUI;
import io.bhex.app.kline.ui.BaseKlineActivity;
import io.bhex.app.kline.ui.KlineFragment;
import io.bhex.baselib.utils.DebugLog;
import io.bhex.sdk.quote.QuoteApi;
import io.bhex.sdk.quote.bean.KLineSocketResponse;
import io.bhex.sdk.socket.NetWorkObserver;
import io.bhex.baselib.constant.AppData;
import io.bhex.baselib.constant.Fields;
import io.bhex.sdk.quote.bean.TickerBean;
import io.bhex.app.utils.DateUtils;
import io.bhex.baselib.mvp.BaseCoreActivity;
import io.bhex.baselib.mvp.BaseFragmentPresenter;

public class KlineFragmentPresenter extends BaseFragmentPresenter<KlineFragmentPresenter.KlineFragmentUI>{
    private static final String TAG = "KlineFragmentPresenter";
    private static final int SHOW_KLINE = 0X0;
    private static final int UPDATE_KLINE = 0X1;
    private static final int UPDATE_KLINES = 0X2;

    private String symbol;
    private String exchangeId="";
    private String mergeDigitsStr;
    //private String currentKlineType=Fields.KLINE_TYPE_DEFAULT_PARAM;//当前K线类型
    private String currentKlineType=KlineKind.KIND_T.replace("kind_t_","");//当前K线类型

    @SuppressLint("HandlerLeak")
    private  Handler mhandler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what){
                case SHOW_KLINE:
                    if (currentKlineData != null) {
//                        if (!currentKlineData.isEmpty()) {
//                            KLineEntity lastData = currentKlineData.get(currentKlineData.size() - 1);
//                        }
                        getUI().showKline(currentKlineData);
                    }
                    break;
                case UPDATE_KLINE:
                    if (currentLastKlineData != null) {
                        getUI().updateKline(currentLastKlineData);
                    }

                    break;
                case UPDATE_KLINES:
                    if (currentKlineData != null) {
                        getUI().updateKlines(currentKlineData);
                    }

                    break;
            }
        }
    };
    private List<KLineEntity> currentKlineData;
    private KLineEntity currentLastKlineData;
    private long from=-1;


    private void handSocketKline(TickerBean tickerBean) {
            KLineEntity kLineEntity = new KLineEntity();

            kLineEntity.msec = Long.valueOf(tickerBean.getT());
            kLineEntity.Date = String.valueOf(DateUtils.str2Date(tickerBean.getT()));
//            kLineEntity.Date = String.valueOf(tickerBean.getT());
            kLineEntity.High = Float.valueOf(tickerBean.getH());
            kLineEntity.Open = Float.valueOf(tickerBean.getO());
            kLineEntity.Low = Float.valueOf(tickerBean.getL());
            kLineEntity.Close =Float.valueOf(tickerBean.getC());
            kLineEntity.Volume = Float.valueOf(tickerBean.getV());
            currentLastKlineData = kLineEntity;
            if (currentKlineData != null) {
                currentKlineData.add(kLineEntity);
                mhandler.sendEmptyMessage(UPDATE_KLINE);
            }
    }

    public interface KlineFragmentUI extends AppUI{

        void showKline(List<KLineEntity> datas);

        void updateKlines(List<KLineEntity> datas);

        void updateKline(KLineEntity item);

        void clearKline();

        void startRequestKline();

        void completeRequestKline();
    }

    @Override
    public void onUIReady(BaseCoreActivity activity, KlineFragmentUI ui) {
        super.onUIReady(activity, ui);
        //DebugLog.d("KlineFragmentPresenter===>","cu=="+currentKlineType);
        Bundle arguments = getFragment().getArguments();
        if (arguments != null) {
            symbol = arguments.getString(AppData.INTENT.SYMBOLS);
            exchangeId = arguments.getString(AppData.INTENT.EXCHANGE_ID);
            mergeDigitsStr = arguments.getString(AppData.INTENT.MERGE_DIGITS);

        }

    }

    @Override
    public void onResume() {
        super.onResume();
        String t_ = "";
        if(KlineKind.KIND_T.endsWith("fenshi")){
            t_="1m";
            ((KlineFragment)getFragment()).switchTime(t_);
        }else{
            int index = KlineKind.KIND_T.lastIndexOf("_");
            t_ = KlineKind.KIND_T.substring(index+1);
            //DebugLog.e("KlineFragmentPresenter==>:","t_="+t_);
            getKline(t_,"500");
        }


    }

    @Override
    public void onPause() {
        super.onPause();
        QuoteApi.UnSubKline( currentKlineType);
    }



    public void switchKline(String klineType) {
        //DebugLog.e("SendMessageWebSocket==>:","UnSubKline=="+ currentKlineType);
        QuoteApi.UnSubKline(currentKlineType);
        currentKlineType = klineType;
        getUI().clearKline();
        if (currentKlineData != null)
            currentKlineData.clear();
        currentLastKlineData = null;
        getKline(currentKlineType, "500");
        //重置开始时间
        from = -1;


    }

    private void getKline(String klineType, String limit) {
        //getUI().showProgressDialog("","");

        getUI().startRequestKline();
        QuoteApi.SubKline(klineType, exchangeId, symbol, limit, new NetWorkObserver<KLineSocketResponse>() {
            @Override
            public void onShowUI(KLineSocketResponse response) {
                if (getUI() == null || !getUI() .isAlive() || response == null)
                    return;
                //getUI().dismissProgressDialog();
                getUI().completeRequestKline();
                List<KLineSocketResponse.LineData> datas = response.data;
                if (datas != null) {
                    handKlineData(datas,false);
                }
            }

            @Override
            public void onError(String error) {
                //getUI().dismissProgressDialog();
                getUI().completeRequestKline();
            }
        });

        long currentTimeMillis = System.currentTimeMillis();
        if(from<0){
            from = currentTimeMillis - DateUtils.calKlineFromTime(klineType);
        }

    }


    public void getKlineHistory() {
        long currentTimeMillis = System.currentTimeMillis();
        if(from<0){
            from = currentTimeMillis - DateUtils.calKlineFromTime(currentKlineType);
        }
        long toTime = 0;
        if(currentKlineData!= null && currentKlineData.size()>0) {
            if (currentKlineData.get(0) != null) {
                toTime = currentKlineData.get(0).getMsec();
            }
            else
                return;

            QuoteApi.GetKlineHistory(currentKlineType, exchangeId, symbol, toTime,"500", new NetWorkObserver<KLineSocketResponse>() {
                @Override
                public void onShowUI(KLineSocketResponse response) {
                    if (getUI() == null || !getUI().isAlive() || response == null)
                        return;

                    List<KLineSocketResponse.LineData> datas = response.data;
                    if (datas != null) {
                        handKlineData(datas, true);
                    }
                }

                @Override
                public void onError(String error) {
                }
            });

        }

    }

    private void handKlineData(List<KLineSocketResponse.LineData> srcDatas, boolean bLeft) {
        if (srcDatas == null || srcDatas.size() == 0)
            return;

        try {
            //数据尺寸正常
            List<KLineEntity> datas = new ArrayList<>();
            for (int i = 0; i < srcDatas.size(); i++) {
                KLineEntity kLineEntity = new KLineEntity();
                kLineEntity.msec = srcDatas.get(i).t;
                kLineEntity.Date = String.valueOf(DateUtils.getSimpleTimeFormat(srcDatas.get(i).t, "MM/dd HH:mm"));
                kLineEntity.High = srcDatas.get(i).h;
                kLineEntity.Open = srcDatas.get(i).o;
                kLineEntity.Low = srcDatas.get(i).l;
                kLineEntity.Close = srcDatas.get(i).c;
                kLineEntity.Volume = srcDatas.get(i).v;
                datas.add(kLineEntity);
            }
            if (currentKlineData != null && !currentKlineData.isEmpty()) {
                //新增数据
                if(bLeft == false) {
                    List<KLineEntity> desDatas = new ArrayList<>();
                    KLineEntity lastKline = currentKlineData.get(currentKlineData.size() - 1);
                    long lastTime = lastKline.getMsec();
                    for (int i = 0; i < datas.size(); i++) {

                        long datetime = datas.get(i).getMsec();
                        if (datetime > lastTime) {
                            //判断是否是所需要的新增数据 ,删除过时数据
                            klineReplaceData(desDatas, datas.get(i));
                        } else if (datetime == lastTime) {
                            //判断是否是所需要的新增数据 ,删除过时数据 两个时间相等时还需要删除历史里最后一根数据，重新添加数据进行更新
                            currentKlineData.remove(lastKline);
                            klineReplaceData(desDatas, datas.get(i));
                        }
                    }

                    currentKlineData.addAll(desDatas);
                }
                else {
                    KLineEntity firstKline = currentKlineData.get(0);
                    long firstTime = firstKline.getMsec();
                    List<KLineEntity> desDatas = new ArrayList<>();
                    for (int i = datas.size() - 1; i >= 0 ; i--) {
                        long datetime = datas.get(i).getMsec();
                        if (datetime < firstTime) {
                            //判断是否是所需要的新增数据 ,删除过时数据
                            desDatas.addAll(datas.subList(0, i));
                            break;
                        } else if (datetime == firstTime) {
                            //判断是否是所需要的新增数据 ,删除过时数据 两个时间相等时还需要删除历史里最后一根数据，重新添加数据进行更新
                            currentKlineData.remove(firstKline);
                            desDatas.addAll(datas.subList(0, i));
                            break;
                        }
                    }

                    currentKlineData.addAll(0,desDatas);
                }
                mhandler.sendEmptyMessage(UPDATE_KLINES);
            } else {
                currentKlineData = datas;
                mhandler.sendEmptyMessage(SHOW_KLINE);
            }

            //赋值最新from

            from = srcDatas.get(srcDatas.size() - 1).t;

        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    private void klineReplaceData(List<KLineEntity> desDatas, KLineEntity data){
        if (desDatas != null && data != null){
            if(desDatas.size() > 0) {
                for (int i = 0; i < desDatas.size(); i++) {
                    if (desDatas.get(i) != null) {
                        if (desDatas.get(i).getMsec() == data.getMsec()) {
                            desDatas.set(i, data);
                            return;
                        }
                    }
                }
                desDatas.add(data);
            }
            else
                desDatas.add(data);
        }

    }
}
